#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"../include/main.h"
#include"../include/movedir.h"
#include"../include/mount_vfs.h"
#include"../include/narrtree.h"
#include"../include/hash.h"
#include"../include/vfs_errorcodes.h"
#include"../include/create_vfs.h"
#include"../include/constants.h"

int found1=0;
int found2=0;
ntree *prev1;
void movedir(char dirname1[],char dirname2[])
{ 
	ntree *parent1,*parent2,*tofind1=NULL,*tofind2=NULL,*tofind,*temp;
	char *pch,dir[MAX_PATH],*k1,temp1[MAX_PATH],temp2[MAX_PATH],*k2,upath[MAX_PATH];
	int i=0,j=0;
	schflag=0;
	if(mounted==0)
		printf("%s_FAILURE %s\n",glb_command,ERR_VFS_MOVEDIR_08);
	else
	{
	while(dirname1[i]!='\0')
	{
		temp1[i]=dirname1[i];
		i++;
	}
	temp1[i]='\0';
	if(strcmp(temp1,"/"))
	{
		k1=strrchr(temp1,'/');
	
		if(k1!=NULL)
		{
			k1++;
			if(*k1 != '\0') {
			tofind1=search_node(head,dirname1);
			}
			else {
			k1--;
			*k1 = '\0';
			tofind1=search_node(head,temp1);
			dirname1 = temp1;
			}
		}
	}
	schflag=0;
	while(dirname2[j]!='\0')
	{
		temp2[j]=dirname2[j];
		j++;
	}
	temp2[j]='\0';
	//if(strcmp(temp2,"/"))
	//{
		k2=strrchr(temp2,'/');
	
		if(k2!=NULL)
		{
			if(!strcmp(temp2,"/"))
				tofind2=search_node(head,dirname2);
			else
			{
				k2++;
				if(*k2 != '\0') {
				tofind2=search_node(head,dirname2);
				}
				else {
				k2--;
				*k2 = '\0';
				tofind2=search_node(head,temp2);
				dirname2 = temp2;
				}
			}
		}
		else
			tofind2=search_node(head,dirname2);
	//}
	schflag=0;
	pch=strrchr(dirname1,'/');
	if(pch!=NULL)
	{
		strcpy(dir,dirname2);
		strcat(dir,pch);
		tofind=search_node(head,dir);
	}
	else
		tofind=search_node(head,dirname1);
	schflag=0;
	i=0;
	while(i<strlen(dirname1))
	{
		if(dirname1[i] != dirname2[i])
			break;
		i++;
	}
	
	
	if(i==strlen(dirname1) && dirname2[i]=='/' )
		printf("%s_FAILURE %s\n",glb_command,ERR_VFS_MOVEDIR_06);
	else if(!strcmp(dirname1,"/"))
		printf("%s_FAILURE %s\n",glb_command,ERR_VFS_MOVEDIR_06);
	else if(tofind1==NULL)
		printf("%s_FAILURE %s\n",glb_command,ERR_VFS_MOVEDIR_01);
	else if(tofind2==NULL)
		printf("%s_FAILURE %s\n",glb_command,ERR_VFS_MOVEDIR_02);
	else if(tofind2->file_desc->filetype==0)
		printf("%s_FAILURE %s\n",glb_command,ERR_VFS_MOVEDIR_07);
	else if(tofind1->file_desc->filetype==0)
		printf("%s_FAILURE %s\n",glb_command,ERR_VFS_MOVEDIR_04);
	else if(tofind != NULL)
		printf("%s_FAILURE %s\n",glb_command,ERR_VFS_MOVEDIR_05);
	else
	{
		parent1 = search1(head,dirname1);
		parent2 = search2(head,dirname2); 
		if(parent1 != NULL)
		if(parent1->next != NULL)
		if(!(strcmp(parent1->next->file_desc->filepath,dirname1)))
		{
			temp=parent1->next;
			strcpy(upath,parent2->file_desc->filepath);
			update_path(temp,upath);
			if(parent2->first == NULL)
			{
				parent2->first = parent1->next ;
				parent1->next = parent1->next->next;
				parent2->first->next=NULL;
			}
			else
			{
				parent2=parent2->first;
				while(parent2->next != NULL)
					parent2=parent2->next;	
				parent2->next = parent1->next ;	
				parent1->next = parent1->next->next;
				parent2->next->next=NULL;	
			}
			printf("movedir_SUCCESS\n");
		
		}
		if(parent1 != NULL)
		if(parent1->first != NULL)
		if(!(strcmp(parent1->first->file_desc->filepath,dirname1)))
		{
			temp=parent1->first;
			strcpy(upath,parent2->file_desc->filepath);
			update_path(temp,upath);
			if(parent2->first == NULL)
			{
				parent2->first = parent1->first ;
				parent1->first = parent1->first->next;
				parent2->first->next=NULL;
			}
			else
			{
				parent2=parent2->first;
				while(parent2->next != NULL)
					parent2=parent2->next;	
				parent2->next = parent1->first ;
				parent1->first = parent1->first->next;
				parent2->next->next=NULL;	
			}
			printf("movedir_SUCCESS\n");
		}
	}
	//traverse(head);
	}
}

void update_path(ntree *temp,char upath[])
{
	ntree *temp4,*q;
	fdesc *temp5;
	llist *temp6;
	char *pch;
	char bakup[MAX_PATH],inbakup[MAX_PATH];
	q=temp;
	if(q!=NULL)
	{
		strcpy(bakup,upath);
		temp4=q;
		do
		{
			strcpy(inbakup,upath);
			temp5 = (fdesc *)malloc(sizeof(fdesc));
			//copy the contents of temp4 to new fdesc and call deletion from hash
			strcpy(temp5->filename,temp4->file_desc->filename);
			strcpy(temp5->filepath,temp4->file_desc->filepath);
			temp5->filetype = temp4->file_desc->filetype;
			temp5->file_size = temp4->file_desc->file_size;
			temp5->blk_num = temp4->file_desc->blk_num;
			int a = deletion(temp5);
			pch=strrchr(temp4->file_desc->filepath,'/');
			strcat(upath,pch);
			strcpy(temp4->file_desc->filepath,upath);
			//copy the contents of temp4 and insert in hash
 			strcpy(temp5->filename,temp4->file_desc->filename);
			strcpy(temp5->filepath,temp4->file_desc->filepath);
			temp5->filetype = temp4->file_desc->filetype;
			temp5->file_size = temp4->file_desc->file_size;
			temp5->blk_num = temp4->file_desc->blk_num;
			 temp6 = insert(temp5);
			update_path(temp4->first,upath);
			temp4=temp4->next;
			strcpy(upath,inbakup);
		}while(temp4!=NULL);
		q=q->first;
	}
}


ntree *search1(ntree * root, char dirname1[])
{
	ntree *parent,*temp,*ans,*in_temp;
	//ntree *prev1;
	temp = root;
	if(temp!=NULL)
	{
		parent=temp;
		do
		{
			if((parent != NULL)&&(found1==0))
			{
				if(!strcmp(parent->file_desc->filepath, dirname1))
				{
					if(prev1->next != NULL)
					if(!strcmp(prev1->next->file_desc->filepath,dirname1))			
						parent = prev1;
					if(prev1->first != NULL)
					if(!strcmp(prev1->first->file_desc->filepath,dirname1))
						parent = prev1;
					found1 = 1;
					//printf("\nsearch1 Returning parentnode    parent->file_desc->filepath==%s\n",parent->file_desc->filepath);
					return parent;
				}
			}
			prev1=parent;
			ans=search1(parent->first,dirname1);
			if(found1==1)
				return ans;
			prev1=parent;
			parent=parent->next;
		}while(parent!=NULL);
		temp=temp->first;
	}
}


ntree *search2(ntree * root, char dirname2[])
{
	ntree *parent,*temp,*ans;
	ntree *prev;
	temp = root;
	if(!strcmp(dirname2,"/"))
	{
		//printf("\nsearch2 Returning node    root->file_desc->filepath==%s\n",root->file_desc->filepath);
		return root;
	}
	if(temp!=NULL)
	{
		parent=temp;
		do
		{
			if((parent != NULL)&&(found2==0))
			{
				if(!strcmp(parent->file_desc->filepath, dirname2))
				{
					found2 = 1;
					//printf("\nsearch2 Returning parentnode    parent->file_desc->filepath==%s\n",parent->file_desc->filepath);
					return parent;
				}
			}
			prev=parent;
			ans=search2(parent->first,dirname2);
			if(found2==1)
				return ans;
			parent=parent->next;
		}while(parent!=NULL);
		temp=temp->first;
	}
}
